using System;
using System.Collections.Generic;
using System.Linq;
using ClientTools.Library.DataTypes.Logging;
using ClientTools.Library.DataTypes.Umbraco;
using ClientTools.Library.DataTypes.Versions;
using ClientTools.Library.Interfaces;
using Log=ClientTools.Library.DataTypes.Logging.Log;
using VersionInfo=ClientTools.Library.DataTypes.Versions.VersionInfo;

namespace ClientTools.Client.Library.Provider
{
    public class WebserviceProvider :
        IProvider,
        ILogging,
        IMedia,
        IVersions
        //Interfaces.IStats,
        //Interfaces.IVersions,
        //Interfaces.IPackager,
        //Interfaces.IMedia
    {

        #region Private Variables

        private readonly ClientToolsWebServices.ClientToolsWebServices services;
        private string serviceUrl;

        #endregion

        #region Local Functions and Properties

        public string ServiceUrl
        {
            get { return serviceUrl; }
            set
            {
                serviceUrl = value;
                services.Url = serviceUrl;
            }
        }

        public string UserName { get; set; }
        public string Password { get; set; }

        public WebserviceProvider()
        {
            services = new ClientToolsWebServices.ClientToolsWebServices();
        }

        public WebserviceProvider(string serviceUrl, string userName, string password)
        {
            this.serviceUrl = serviceUrl;
            if (!this.serviceUrl.EndsWith("/"))
                this.serviceUrl += "/";

            services = new ClientToolsWebServices.ClientToolsWebServices {Url = this.serviceUrl};

            UserName = userName;
            Password = password;
        }

        #endregion

        #region Datatype Conversions

        //private ClientTools.Library.Stats.StatsInfo ConvertStatsInfo(MaintenanceService.StatsInfo serviceStatsInfo)
        //{
        //    ClientTools.Library.Stats.StatsInfo returnValue = new ClientTools.Library.Stats.StatsInfo();
        //    returnValue.Entries = serviceStatsInfo.Entries;
        //    returnValue.Sessions = serviceStatsInfo.Sessions;
        //    return returnValue;
        //}

        //private static ClientTools.Library.DataTypes.Versions.VersionInfo ConvertVersionInfo(MaintenanceService.VersionInfo serviceVersionInfo)
        //{
        //    var returnValue = new ClientTools.Library.DataTypes.Versions.VersionInfo
        //                          {
        //                              Documents = serviceVersionInfo.Documents,
        //                              PropertyData = serviceVersionInfo.PropertyData,
        //                              Versions = serviceVersionInfo.Versions
        //                          };
        //    return returnValue;
        //}

        ////private static ClientTools.Library.Macros.MacroCollection ConvertMacroCollection(IEnumerable<Macro> serviceMacros)
        ////{
        ////    var returnValue = new ClientTools.Library.Macros.MacroCollection();
        ////    foreach (var serviceMacro in serviceMacros)
        ////    {
        ////        var macro = new ClientTools.Library.Macros.Macro
        ////                        {
        ////                            Alias = serviceMacro.Alias,
        ////                            Assembly = serviceMacro.Assembly,
        ////                            Id = serviceMacro.Id,
        ////                            Name = serviceMacro.Name,
        ////                            RefreshRate = serviceMacro.RefreshRate,
        ////                            Type = serviceMacro.Type,
        ////                            UseInEditor = serviceMacro.UseInEditor,
        ////                            Xslt = serviceMacro.Xslt,
        ////                            Properties = ConvertMacroPropertyCollection(serviceMacro.Properties)
        ////                        };
        ////        returnValue.Add(macro);
        ////    }
        ////    return returnValue;
        ////}

        ////private static ClientTools.Library.Macros.MacroPropertyCollection ConvertMacroPropertyCollection(IEnumerable<MacroProperty> serviceMacroProperties)
        ////{
        ////    var returnValue = new ClientTools.Library.Macros.MacroPropertyCollection();
        ////    foreach (var serviceMacroProperty in serviceMacroProperties)
        ////    {
        ////        var macroProperty = new ClientTools.Library.Macros.MacroProperty
        ////                                {
        ////                                    Alias = serviceMacroProperty.Alias,
        ////                                    Name = serviceMacroProperty.Name,
        ////                                    Public = serviceMacroProperty.Public,
        ////                                    SortOrder = serviceMacroProperty.SortOrder,
        ////                                    Type = serviceMacroProperty.Type
        ////                                };
        ////        returnValue.Add(macroProperty);
        ////    }
        ////    return returnValue;
        ////}

        ////private static ClientTools.Library.DocumentTypes.DocumentTypeCollection ConvertDocumentTypeCollection(IEnumerable<DocumentType> serviceDocumentTypes)
        ////{
        ////    var returnValue = new ClientTools.Library.DocumentTypes.DocumentTypeCollection();
        ////    foreach (DocumentType serviceDocumentType in serviceDocumentTypes)
        ////    {
        ////        var docType = new ClientTools.Library.DocumentTypes.DocumentType {Alias = serviceDocumentType.Alias};
        ////        foreach (string allowedDocumentType in serviceDocumentType.AllowedChilds)
        ////        {
        ////            docType.AllowedChilds.Add(allowedDocumentType);
        ////        }
        ////        docType.DefaultTemplate = serviceDocumentType.DefaultTemplate;
        ////        foreach (GenericProperty serviceGenericProperty in serviceDocumentType.GenericProperties)
        ////        {
        ////            var genericProperty = new ClientTools.Library.DocumentTypes.GenericProperty
        ////                                      {
        ////                                          Alias = serviceGenericProperty.Alias,
        ////                                          Description = serviceGenericProperty.Description.Value,
        ////                                          Mandatory = serviceGenericProperty.Mandatory,
        ////                                          Name = serviceGenericProperty.Name,
        ////                                          Tab = serviceGenericProperty.Tab,
        ////                                          Type = serviceGenericProperty.Type,
        ////                                          Validation = serviceGenericProperty.Validation
        ////                                      };
        ////            docType.GenericProperties.Add(genericProperty);
        ////        }
        ////        docType.Icon = serviceDocumentType.Icon;
        ////        docType.Name = serviceDocumentType.Name;
        ////        foreach (Tab serviceTab in serviceDocumentType.Tabs)
        ////        {
        ////            var tab = new ClientTools.Library.DocumentTypes.Tab
        ////                          {
        ////                              Caption = serviceTab.Caption,
        ////                              Id = serviceTab.Id
        ////                          };
        ////            docType.Tabs.Add(tab);
        ////        }
        ////        foreach (string template in serviceDocumentType.Templates)
        ////        {
        ////            docType.Templates.Add(template);
        ////        }
        ////        docType.Thumbnail = serviceDocumentType.Thumbnail;
        ////        returnValue.Add(docType);
        ////    }
        ////    return returnValue;
        ////}

        ////private static ClientTools.Library.Templates.TemplateCollection ConvertTemplateCollection(IEnumerable<Template> serviceTemplates)
        ////{
        ////    var returnValue = new ClientTools.Library.Templates.TemplateCollection();
        ////    foreach (Template serviceTemplate in serviceTemplates)
        ////    {
        ////        var template = new ClientTools.Library.Templates.Template
        ////                           {
        ////                               Alias = serviceTemplate.Alias,
        ////                               Design = serviceTemplate.Design,
        ////                               MasterTemplate = serviceTemplate.MasterTemplate,
        ////                               Name = serviceTemplate.Name
        ////                           };
        ////        returnValue.Add(template);
        ////    }
        ////    return returnValue;
        ////}

        //private ClientTools.Library.DataTypes.Nodes.NodeCollection ConvertNodeCollection(List<MaintenanceService.Node> serviceNodes)
        //{
        //    var returnValue = new ClientTools.Library.DataTypes.Nodes.NodeCollection();
        //    foreach (MaintenanceService.Node serviceNode in serviceNodes)
        //    {
        //        returnValue.Add(ConvertNode(serviceNode));
        //    }
        //    return returnValue;
        //}

        //private ClientTools.Library.DataTypes.Nodes.Node ConvertNode(MaintenanceService.Node serviceNode)
        //{
        //    var returnValue = new ClientTools.Library.DataTypes.Nodes.Node { Id = serviceNode.Id, Name = serviceNode.Name, NodeTypeAlias = serviceNode.NodeTypeAlias, NodeTypeId = serviceNode.NodeTypeId, VersionCount = serviceNode.VersionCount, ChildrenVersionCount = serviceNode.ChildrenVersionCount };
        //    foreach (var item in serviceNode.Properties)
        //        returnValue.Properties.Add(new ClientTools.Library.DataTypes.Nodes.Property() { Id = item.Id, Value = item.Value, PropertyTypeId = item.PropertyTypeId, PropertyTypeAlias = item.PropertyTypeAlias });
        //    returnValue.Children = this.ConvertNodeCollection(serviceNode.Children);

        //    return returnValue;
        //}

        //private ClientTools.Library.Versions.VersionCollection ConvertVersionCollection(List<MaintenanceService.Version> serviceVersions)
        //{
        //    ClientTools.Library.Versions.VersionCollection returnValue = new ClientTools.Library.Versions.VersionCollection();
        //    foreach (var item in serviceVersions)
        //        returnValue.Add(new ClientTools.Library.Versions.Version() { UpdateDate = item.UpdateDate, Guid = item.Guid, Id = item.Id, IsNewest = item.IsNewest, Published = item.Published, Text = item.Text, UserId = item.UserId, UserName = item.UserName, VersionDate = item.VersionDate });
        //    return returnValue;
        //}

        #endregion

        ////#region I_Stats Member

        ////ClientTools.Library.Stats.StatsInfo Interfaces.IStats.DeleteStatsByDate(DateTime date)
        ////{
        ////    throw new NotImplementedException();
        ////    //return this.ConvertStatsInfo(this.maintenanceService.DeleteStatsByDate(this.userName, this.password, date));
        ////}

        ////ClientTools.Library.Stats.StatsInfo Interfaces.IStats.GetStatsInfo()
        ////{
        ////    throw new NotImplementedException();
        ////    //return this.ConvertStatsInfo(this.maintenanceService.GetStatsInfo(this.userName, this.password));
        ////}

        ////#endregion

        //        #region I_Versions Member

        //        public ClientTools.Library.Versions.VersionInfo GetVersionInfos()
        //        {

        //            return this.ConvertVersionInfo(this.maintenanceService.GetVersionInfos(this.userName, this.password));
        //        }

        //        public ClientTools.Library.Versions.VersionInfo XX_DeleteVersionsByDate(DateTime date)
        //        {
        //            throw new NotImplementedException();
        //            return this.ConvertVersionInfo(this.maintenanceService.DeleteVersionsByDate(this.userName, this.password, date, -1));
        //        }

        //        public ClientTools.Library.Versions.VersionInfo XX_DeleteVersionsByNumberOfItems(int numberOfItems)
        //        {
        //            throw new NotImplementedException();
        //            return this.ConvertVersionInfo(this.maintenanceService.DeleteVersionsByNumberOfItems(this.userName, this.password, numberOfItems, -1));
        //        }

        //        public ClientTools.Library.Versions.VersionCollection GetVersions(int id)
        //        {
        //            return this.ConvertVersionCollection((from x in this.maintenanceService.GetVersions(userName, password, id) orderby x.UpdateDate descending select x).ToList()); 
        //        }

        //        public ClientTools.Library.Versions.VersionInfo DeleteVersion(Guid guid)
        //        {
        //            return this.ConvertVersionInfo(this.maintenanceService.DeleteVersion(userName, password, guid));
        //        }

        //        public ClientTools.Library.Versions.VersionInfo GetChildrenVersionInfos(int id)
        //        {
        //            return this.ConvertVersionInfo(this.maintenanceService.GetChildrenVersionInfos(userName, password, id));
        //        }

        //        public ClientTools.Library.Versions.VersionInfo GetNodeVersionInfos(int id)
        //        {
        //            return this.ConvertVersionInfo(this.maintenanceService.GetChildrenVersionInfos(userName, password, id));
        //        }

        //        ClientTools.Library.Versions.VersionInfo ClientTools.Client.Library.Interfaces.IVersions.GetNodeVersionInfos(int id)
        //        {
        //            return this.ConvertVersionInfo(this.maintenanceService.GetNodeVersionInfos(userName, password, id));
        //        }

        //        public ClientTools.Library.Versions.VersionInfo DeleteVersionsByDate(DateTime date, int id)
        //        {
        //            return this.ConvertVersionInfo(this.maintenanceService.DeleteVersionsByDate(userName, password, date, id );
        //            throw new NotImplementedException();
        //        }

        //#endregion

        //public ClientTools.Library.DataTypes.Nodes.NodeCollection GetNodes(int parentId, bool recursive)
        //{
        //    return this.ConvertNodeCollection(this.maintenanceService.GetNodes(userName, password, parentId, recursive));
        //}

        ////#region IPackager Member

        ////public ClientTools.Library.Macros.MacroCollection GetMacros()
        ////{
        ////    var request = new GetMacrosRequest
        ////                      {
        ////                          Body =
        ////                              new GetMacrosRequestBody(userName,
        ////                                                       password)
        ////                      };
        ////    return ConvertMacroCollection(packageService.GetMacros(userName, password));
        ////}

        ////public ClientTools.Library.Templates.TemplateCollection GetTemplates()
        ////{
        ////    return ConvertTemplateCollection(packageService.GetTemplates(userName, password));
        ////}

        ////public ClientTools.Library.DocumentTypes.DocumentTypeCollection GetDocumentTypes()
        ////{
        ////    return ConvertDocumentTypeCollection(packageService.GetDocumentTypes(userName, password));
        ////}

        ////#endregion

        ////#region IMedia Members

        ////public ClientTools.Library.Media.MediaCollection GetRootMedias(bool recursive)
        ////{
        ////    return ConvertMediaCollection(mediaService.GetRootMedias(userName, password, recursive));
        ////}

        ////public ClientTools.Library.Media.MediaCollection GetMedias(int parentId, bool recursive)
        ////{
        ////    return ConvertMediaCollection(mediaService.GetMedias(userName, password, parentId, recursive));
        ////}

        ////bool Interfaces.IMedia.DeleteMedia(int mediaId)
        ////{
        ////    return mediaService.DeleteMedia(userName, password, mediaId);
        ////}

        ////public ClientTools.Library.Media.Media CreateImage(int parentId, string fileName, byte[] content)
        ////{
        ////    return ConvertMedia(mediaService.CreateImage(userName, password, parentId, fileName, content));
        ////}

        ////public ClientTools.Library.Media.Media CreateFile(int parentId, string fileName, byte[] content)
        ////{
        ////    return ConvertMedia(mediaService.CreateFile(userName, password, parentId, fileName, content));
        ////}

        ////public ClientTools.Library.Media.Media CreateFolder(int parentId, string folderName)
        ////{
        ////    return ConvertMedia(mediaService.CreateFolder(userName, password, parentId, folderName));
        ////}

        ////#endregion

        ////#region IVersions Members

        ////public ClientTools.Library.DataTypes.Versions.VersionInfo GetVersionInfos()
        ////{
        ////    return ConvertVersionInfo(this.maintenanceService.GetVersionInfos(this.userName, this.password));
        ////}

        ////public ClientTools.Library.DataTypes.Versions.VersionInfo GetVersionInfos(int nodeId)
        ////{
        ////    return ConvertVersionInfo(this.maintenanceService.GetVersionInfosByNode(this.userName, this.password, nodeId, false));
        ////}

        ////public ClientTools.Library.DataTypes.Versions.VersionInfo GetVersionInfos(int nodeId, bool includeChildren)
        ////{
        ////    return ConvertVersionInfo(this.maintenanceService.GetVersionInfosByNode(this.userName, this.password, nodeId, includeChildren));
        ////}

        ////public ClientTools.Library.DataTypes.Versions.VersionInfo GetChildrenVersionInfos(int nodeId)
        ////{
        ////    return ConvertVersionInfo(this.maintenanceService.GetChildrenVersionInfos(this.userName, this.password, nodeId));
        ////}

        ////public ClientTools.Library.DataTypes.Versions.VersionCollection GetVersions(int nodeId)
        ////{
        ////    return this.ConvertVersionCollection(this.maintenanceService.GetVersions(this.userName, this.password, nodeId));
        ////}

        ////public ClientTools.Library.Versions.VersionInfo XX_DeleteVersionsByDate(DateTime date)
        ////{
        ////    throw new NotImplementedException();
        ////}

        ////public ClientTools.Library.Versions.VersionInfo XX_DeleteVersionsByNumberOfItems(int numberOfItems)
        ////{
        ////    throw new NotImplementedException();
        ////}

        ////public ClientTools.Library.Versions.VersionInfo DeleteVersion(Guid guid)
        ////{
        ////    return ConvertVersionInfo(this.maintenanceService.DeleteVersion(this.userName, this.password, guid));
        ////}

        ////public ClientTools.Library.Versions.VersionInfo DeleteVersionsByDate(DateTime date, int id)
        ////{
        ////    throw new NotImplementedException();
        ////}

        ////#endregion

      
        ////#region IMedia Members

        ////ClientTools.Library.Media.MediaCollection ClientTools.Client.Library.Interfaces.IMedia.GetRootMedias(bool recursive)
        ////{
        ////    throw new NotImplementedException();
        ////}

        ////ClientTools.Library.Media.MediaCollection ClientTools.Client.Library.Interfaces.IMedia.GetMedias(int parentId, bool recursive)
        ////{
        ////    throw new NotImplementedException();
        ////}

        ////ClientTools.Library.Media.Media ClientTools.Client.Library.Interfaces.IMedia.CreateImage(int parentId, string fileName, byte[] content)
        ////{
        ////    throw new NotImplementedException();
        ////}

        ////ClientTools.Library.Media.Media ClientTools.Client.Library.Interfaces.IMedia.CreateFile(int parentId, string fileName, byte[] content)
        ////{
        ////    throw new NotImplementedException();
        ////}

        ////ClientTools.Library.Media.Media ClientTools.Client.Library.Interfaces.IMedia.CreateFolder(int parentId, string folderName)
        ////{
        ////    throw new NotImplementedException();
        ////}

        ////#endregion

        #region IProvider Members

        public string ProviderName
        {
            get { return "Webservice Provider"; }
        }

        public Guid Guid
        {
            get { return new Guid("{C2E264F5-07B3-472d-8D8D-244E8A7B0367}"); }
        }

        public int SortOrder
        {
            get { return 0; }
        }

        #endregion

        #region ILogging Members

        LogInfoCollection ILogging.GetLogInfos()
        {
            var returnValue = new LogInfoCollection();
            returnValue.AddRange(from x in services.GetLogInfos(UserName, Password) select new LogInfo { Count = x.Count, LogHeader = x.LogHeader });
            return returnValue;
        }

        LogCollection ILogging.GetLogs(DateTime? startDate, DateTime? endDate, string logHeader, int? userId, int? nodeId, int? maxRows, string comment)
        {
            var returnValue = new LogCollection();
            returnValue.AddRange(
                from x in
                    services.GetLogs(UserName, Password, startDate, endDate, logHeader, userId, nodeId,
                                               maxRows, comment)
                select
                    new Log
                    {
                        Id = x.Id,
                        DateStamp = x.DateStamp,
                        LogComment = x.LogComment,
                        LogHeader = x.LogHeader,
                        NodeId = x.NodeId,
                        UserId = x.UserId
                    });
            return returnValue;
        }

        int ILogging.DeleteLogsByHeader(string logHeader)
        {
            return services.DeleteLogsByHeader(UserName, Password, logHeader);
        }

        int ILogging.DeleteLogsByDate(DateTime date)
        {
            return services.DeleteLogsByDate(UserName, Password, date);
        }

        int ILogging.DeleteLogsByIDs(List<int> logIds)
        {
            return services.DeleteLogsById(UserName, Password, logIds.ToArray());
        }

        #endregion

        #region IMedia Members

        NodeCollection IMedia.GetRootMedias(bool recursive)
        {
            return services.GetRootMedias(UserName, Password, recursive).ToNodeCollection();
        }

        NodeCollection IMedia.GetMedias(int parentId, bool recursive)
        {
            return services.GetMedias(UserName, Password, parentId, recursive).ToNodeCollection();
        }

        bool IMedia.DeleteMedia(int mediaId)
        {
            return services.DeleteMedia(UserName, Password, mediaId);
        }

        Node IMedia.CreateImage(int parentId, string fileName, byte[] content)
        {
            return services.CreateImage(UserName, Password, parentId, fileName, content).ToNode();
        }

        Node IMedia.CreateFile(int parentId, string fileName, byte[] content)
        {
            return services.CreateFile(UserName, Password, parentId, fileName, content).ToNode();
        }

        Node IMedia.CreateFolder(int parentId, string folderName)
        {
            return services.CreateFolder(UserName, Password, parentId, folderName).ToNode();
        }

        #endregion

        #region IVersions Members

        public VersionInfo GetVersionInfos()
        {
            return services.GetVersionInfos(UserName, Password).ToVersionInfo();
        }

        public VersionInfo GetVersionInfos(int nodeId)
        {
            return services.GetVersionInfosFromNode(UserName, Password, nodeId, false).ToVersionInfo();
        }

        public VersionInfo GetVersionInfos(int nodeId, bool includeChildren)
        {
            return services.GetVersionInfosFromNode(UserName, Password, nodeId, includeChildren).ToVersionInfo();
        }

        public VersionInfo GetChildrenVersionInfos(int nodeId)
        {
            return services.GetChildrenVersionInfos(UserName, Password, nodeId).ToVersionInfo();
        }

        public VersionCollection GetVersions(int nodeId)
        {
            return services.GetVersions(UserName, Password, nodeId).ToVersionCollection();
        }

        public VersionInfo DeleteVersion(Guid guid)
        {
            return services.DeleteVersion(UserName, Password, guid).ToVersionInfo();
        }

        public VersionInfo DeleteVersionsByDate(DateTime date)
        {
            return services.DeleteVersionsByDate(UserName, Password, date).ToVersionInfo();
        }

        public VersionInfo DeleteVersionsByDate(DateTime date, int nodeId)
        {
            return services.DeleteNodeVersionsByDate(UserName, Password, date, nodeId).ToVersionInfo();
        }

        public VersionInfo DeleteVersionsByItems(int numberOfItems)
        {
            return services.DeleteVersionsByItems(UserName, Password, numberOfItems).ToVersionInfo();
        }

        public VersionInfo DeleteVersionsByItems(int numberOfItems, int nodeId)
        {
            return services.DeleteNodeVersionsByItems(UserName, Password, numberOfItems, nodeId).ToVersionInfo();
        }

        #endregion

        //#region IVersions Members


        //public VersionInfo DeleteVersionsByDate(DateTime date, int id)
        //{
        //    throw new NotImplementedException();
        //}

        //public VersionInfo DeleteVersionsByItems(DateTime date, int id)
        //{
        //    throw new NotImplementedException();
        //}

        //#endregion

        #region INodes Members

        public NodeCollection GetNodes(int parentId, bool recursive)
        {
            return services.GetNodes(UserName, Password, parentId, recursive).ToNodeCollection();
        }

        #endregion
    }
}
